SpringApplication allows an application to be initialized lazily. When lazy initialization is enabled, beans are created as they are needed rather than during application startup. As a result, enabling lazy initialization can reduce the time that it takes your application to start. In a web application, enabling lazy initialization will result in many web-related beans not being initialized until an HTTP request is received.
SpringApplication 允許一個應用去延遲加載
當開啟延遲加載,beans(Spring Beans) 不會在應用啟動階段就去備妥,取而代之是在有需要這些 beans 的時候去創建。懶惰加載可以減少應用啟動時間。在(web) 應用,延遲加載會影響許多跟網路相關的 beans 不會被加載,直到收到 HTTP 請求的時候才會建立。
A downside of lazy initialization is that it can delay the discovery of a problem with the application. If a misconfigured bean is initialized lazily, a failure will no longer occur during startup and the problem will only become apparent when the bean is initialized. Care must also be taken to ensure that the JVM has sufficient memory to accommodate all of the application’s beans and not just those that are initialized during startup. For these reasons, lazy initialization is not enabled by default and it is recommended that fine-tuning of the JVM’s heap size is done before enabling lazy initialization.
官方提及,延遲加載有一缺點就是會讓應用問題的發現也會…延遲。
假若一個 bean ,他是註冊有錯誤的 bean,但因為延遲加載,所以有可能直到 HTTP 需求發來的時候才會被發現; 所以官方是預設是把延遲加載關閉的。 如果需要開啟延遲加載的話,官方建議在開啟之前, JVM 堆空間(heap size) 已經進行微調 。
這裡為什麼會提到 JVM 堆空間 ,因為延遲加載是在需要時候才會創建 beans,而且一次加載可能因為相依注入而需要不只一個 bean 的空間,所以這裡特別建議去做 JVM heap size 的微調。
Lazy initialization can be enabled programmatically using the lazyInitialization method on SpringApplicationBuilder or the setLazyInitialization method on SpringApplication. Alternatively, it can be enabled using the spring.main.lazy-initialization property 。
有幾種方式可以開啟延遲加載一是透過程式碼的方式,由 SpringApplicationBuilder 之下的lazyInitialization 或是setLazyInitialization 方法 ; 另一個方面是透過外掛註冊的方式,其註冊內容如下
spring:
main:
lazy-initialization: true
上述提供兩種方式SpringApplicationBuilder 和外掛註冊(application.yml 或是 application.properties ) ,這兩個如果要選擇的話筆者會偏好選擇後者,可以將所有的屬性都寫在同一份註冊,而註冊檔案有可以根據不同環境如開發的dev、uat、或是正式的 prod 去做區分;另一面如果是透過程式碼(SpringApplicationBuilder、SpringApplication) 在一個專案下只能產生一份的程式碼,如果有兩個環境dev、uat,一個要開啟延遲加載、另一個沒有,就不能區別開來。
參考資料
{官方} Lazy Initialization
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.spring-application.lazy-initialization